package lumis.service.pagepersonalization.widgetmanipulationaction;

import lumis.content.ContentManagerFactory;
import lumis.portal.PortalException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.manager.ManagerFactoryInternal;
import lumis.portal.preferences.IPreferences;
import lumis.portal.presentation.perspective.IPortalMode;
import lumis.portal.serviceinterfaceinstance.ServiceInterfaceInstanceConfig;
import lumis.portal.transaction.ITransaction;
import lumis.service.pagepersonalization.PagePersonalizationUtil;
import lumis.service.pagepersonalization.bean.PagePersonalizationHolderConfiguration;
import lumis.service.pagepersonalization.bean.Widget;
import lumis.service.pagepersonalization.bean.PagePersonalizationHolderConfiguration.Type;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * An {@link AbstractWidgetManipulationAction} implementation for removing user
 * widgets. Requires the following parameters:
 * <ul>
 * <li><b>wci</b>: The widget content identifier.</li>
 * <li><b>hi</b>: The holder service interface instance identifier.</li>
 * </ul>
 *
 * @version $Revision: 13246 $ $Date: 2011-07-14 17:08:26 -0300 (Thu, 14 Jul 2011) $
 * @since 6.0.0
 */
public class RemoveWidgetAction extends AbstractWidgetManipulationAction
{
	private static final String INTERFACE_INSTANCE_ID_ID = "ii";
	private static final String HOLDER_INSTANCE_ID = "hi";
	private static final String[] REQUIRED_PARAMETERS = new String[] { INTERFACE_INSTANCE_ID_ID, HOLDER_INSTANCE_ID };

	@Override
	String[] getRequiredParameters()
	{
		return REQUIRED_PARAMETERS;
	}

	@Override
	int processWidgetManipulation(HttpServletRequest request, IPortalMode portalMode, ITransaction transaction) throws PortalException
	{
		// read holder
		SessionConfig sessionConfig = SessionConfig.getCurrentSessionConfig();
		String holderServiceInterfaceInstanceId = getParameter(HOLDER_INSTANCE_ID, request);
		ServiceInterfaceInstanceConfig holderServiceInterfaceInstanceConfig = ManagerFactory.getServiceInterfaceInstanceManager().get(sessionConfig, holderServiceInterfaceInstanceId, transaction);
		
		// read widget
		String widgetInterfaceInstanceId = getParameter(INTERFACE_INSTANCE_ID_ID, request);
		Widget widget = Widget.getByInterfaceInstanceId(widgetInterfaceInstanceId);
		if (widget == null)
			return HttpServletResponse.SC_BAD_REQUEST;

		String widgetId = widget.getId();
		String widgetContentId = ContentManagerFactory.getContentManager().getContentVersionByItemId(widgetId)
				.getContentLocale().getContent().getId();

		if (portalMode.getId() == IPortalMode.MODE_PERSONALIZATION)
		{
			// check permission for managing holder
			checkManageHolderPermission(holderServiceInterfaceInstanceConfig.getServiceInstanceId());
			
			// get current widgets...
			PagePersonalizationHolderConfiguration tempHolderConfig = PagePersonalizationHolderConfiguration.getByTypeAndHolderInstanceId(Type.Temporary,
					holderServiceInterfaceInstanceId);
			if (tempHolderConfig == null)
				return HttpServletResponse.SC_BAD_REQUEST;

			// removes the widget
			String[] widgets = tempHolderConfig.expand();
			List<String> list = new ArrayList<String>(widgets.length);
			Collections.addAll(list, widgets);
			if (!list.remove(widgetContentId))
				return HttpServletResponse.SC_BAD_REQUEST;
			tempHolderConfig.setWidgets(list);
			return HttpServletResponse.SC_OK;
		}
		else
		{
			// check permission for personalizing page
			checkPersonalizePagePermission(holderServiceInterfaceInstanceConfig.getServiceInstanceId());
			
			Lock clusterLock = ManagerFactory.getLockManager().getLock("lumis.pagepersonalization.widgetholder.preferences#"+sessionConfig.getUserId());
			
			try
			{

				clusterLock.lock();
				// get current widgets...
				IPreferences preferences = ManagerFactory.getPreferencesManager().getPreferences(SessionConfig.getCurrentSessionConfig(),
						holderServiceInterfaceInstanceId, IPreferences.TYPE_SERVICE_INTERFACE_INSTANCE);
	
				String[] values = preferences.getValues(PagePersonalizationUtil.WIDGETS_PREFERENCES_NAME,
						PagePersonalizationUtil.getDefaultWidgets(SessionConfig.getCurrentSessionConfig(),
								holderServiceInterfaceInstanceId, Type.Default, transaction));
	
				if (values == null || values.length == 0)
					return HttpServletResponse.SC_BAD_REQUEST;
	
				List<String> valuesList = new ArrayList<String>(values.length);
				Collections.addAll(valuesList, values);
				if (!valuesList.remove(widgetContentId))
					return HttpServletResponse.SC_BAD_REQUEST;
				values = valuesList.toArray(new String[valuesList.size()]);
				try
				{
					preferences.setValues(PagePersonalizationUtil.WIDGETS_PREFERENCES_NAME, values);
					preferences.store();
				}
				catch (Exception e)
				{
					return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
				}
				
				// stores preferences to the other holders on the page.
				// gets other holders ids of the page.
				String pageId = ManagerFactoryInternal.getServiceInterfaceInstanceManager().get(sessionConfig, holderServiceInterfaceInstanceConfig.getId(), transaction).getPageId();
				Collection<String> serviceInterfaceInstanceIds = ManagerFactory.getServiceInterfaceInstanceManager().getIdsByPageId(sessionConfig, pageId, transaction);
				for (String id : serviceInterfaceInstanceIds)
				{
					ServiceInterfaceInstanceConfig serviceInterfaceInstanceConfig = ManagerFactoryInternal.getServiceInterfaceInstanceManager().get(sessionConfig, id, transaction);
					if (serviceInterfaceInstanceConfig.getServiceInterfaceId().equalsIgnoreCase(LUMIS_SERVICE_PAGEPERSONALIZATION_WIDGET_HOLDER_INTERFACE_ID) && !holderServiceInterfaceInstanceConfig.getId().equalsIgnoreCase(id))
					{
						// get current widgets...
						preferences = ManagerFactory.getPreferencesManager().getPreferences(sessionConfig,
								id, IPreferences.TYPE_SERVICE_INTERFACE_INSTANCE);
	
						values = preferences.getValues(PagePersonalizationUtil.WIDGETS_PREFERENCES_NAME, null);
						if (values == null)
						{
							values = PagePersonalizationUtil.getDefaultWidgets(sessionConfig,
									id, Type.Default, transaction);
						}
						
						if (values == null)
							values = new String[] {};
	
						try
						{
							preferences.setValues(PagePersonalizationUtil.WIDGETS_PREFERENCES_NAME, values);
							preferences.store();
						}
						catch (Exception e)
						{
							return HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
						}
					}
				}
			}
			finally
			{
				clusterLock.unlock();
			}
			return HttpServletResponse.SC_OK;
		}
	}
}
